const webpack = require("webpack")
// node 的 path 模块
const path = require("path") 
// HtmlWebpackPlugin
const HtmlWebpackPlugin = require("html-webpack-plugin")
// 自定义plugin
const pluginDemo = require("./src/plugin-demo/plugin-fileList")
// 分析unused exports 需要设置为true，production下默认是true
const DeadCodePlugin = require("webpack-deadcode-plugin")
// const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const DashboardPlugin = require("webpack-dashboard/plugin")
const WebpackBuildNotifierPlugin = require("webpack-build-notifier")
const CmpressionWebpackPlugin = require("compression-webpack-plugin")
/**
 * css tree shaking
 */
const glob = require("glob")
const globAll = require("glob-all")
const src =  path.resolve(__dirname, "./src")
const htmlPath =  path.resolve(__dirname, "public/")
const pathes = globAll.sync([
	`${src}**/*.js`,
	`${htmlPath}**/*.html`

])
console.log(pathes)
const pathJoin =  glob.sync(path.join(__dirname, "src/**/*.{html,js}"))
console.log(pathJoin)
const { PurgeCSSPlugin }  = require("purgecss-webpack-plugin")
// 清空 打包目录
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
//common.js语法

module.exports = {
	context: path.resolve(__dirname, "./src"), // *基础目录，绝对路径，用于从配置中解析入口点(entry point)和 加载器(loader)。该配置会影响入口和loaders的解析，入口和loaders的相对路径会以context的配置作为基准路径，这样，你的配置会独立于CWD（current working directory 
  
	entry:{
		main:"./main.js", // *多入口文件依次写入： 文件名：‘相对路径’
		// index:'./index.js', // *多入口文件依次写入： 文件名：‘相对路径’
		about:"./about.js",
		// page1:'./autoDll/page1.js',
		// page2:'./autoDll/page2.js',
		// home: {
		//   import: './home.js',
		//   filename: 'src/home.js',
		//   dependOn: 'main',  //*共享
		//   chunkLoading: false, // *禁用按需加载的块，并将所有内容放入主块中。  代码分割
		// },
		// about: {
		//   import: './about.js',
		//   filename: './about.js',
		//   dependOn: 'main',
		//   chunkLoading: 'jsonp',
		//   asyncChunks: true, // *创建按需加载的异步块。，需要使用 optimization.splitChunks 选项，并将其设置为一个对象。在该对象中，可以使用 cacheGroups 属性来定义各个分组的条件和参数。
		//   layer: 'name of layer', // *为入口点设置图层
		// },

	},
	output:{

		// assetModuleFilename: 'assets/[name][hash][ext][query]',// *与 output.filename 相同，不过应用于 Asset Modules(资源模块，前提需要理解 webpack编译过程)。 具体需要配合rules详细请看文档outPut/assetModuleFilename.md

      
		path:path.resolve(__dirname,"dist"),
		pathinfo:true, //*webpack 在 bundle 中引入「所包含模块信息」的相关注释 对于在开发环境(development)下阅读生成代码时，虽然通过这些注释可以提供有用的数据信息，但在生产环境(production)下，不应该使用。
		publicPath:"",

		filename:"js/[name].[contenthash:8].bundle.js",

		sourceMapFilename:"map/[name].[contenthash:8].map.js",
		chunkFilename: "js/[name].[contenthash]chunk.js",
		//[id]	此 chunk 的 ID
		//* [name]	如果设置，则为此 chunk 的名称，否则使用 chunk 的 ID
		//* [chunkhash]	此 chunk 的 hash 值，包含该 chunk 的所有元素
		//* [contenthash]	此 chunk 的 hash 值，只包括该内容类型的元素（受 optimization.realContentHash 影响）
		asyncChunks:true,// 创建按需加载的异步 chunk。
		// module:true,
		library:"[name]",
		// library: {
       
		//   type:'var', //  module类型不要在此处指定“名称”
		//   name:'MyLib'
		// }, //* https://www.webpackjs.com/configuration/output/#outputlibrary
		// libraryTarget: 'umd', //* 使用library.type 代理这个属性，这个未来即将放弃
		// auxiliaryComment:'Test Comment',  //*在和 output.library 和 output.libraryTarget 一起使用时，此选项允许用户向导出容器(export wrapper)中插入注释。要为 libraryTarget 每种类型都插入相同的注释，将 auxiliaryComment 设置为一个字符串：
		devtoolFallbackModuleFilenameTemplate: "fallback-[absoluteResourcePath]",  //*用于指定 Source Map 文件中无法找到源代码的模块时，如何生成替代的文件名。
		// devtoolModuleFilenameTemplate: (info) => {
		//   return `webpack:///${info.resourcePath}?${info.loaders}`;
		// },
     
	},
  
	resolve: {
		alias: {
			"@": path.resolve(__dirname, "src"),  // 别名
			"core-js": path.resolve(__dirname, "node_modules/core-js"),
     
		},
		modules: ["node_modules"] , //*解析模块时，如果遇到导入语句，```require("test")```，webpack会从下面的位置寻找依赖的模块
		extensions: [".js", ".ts"],//*当解析模块时，遇到无具体后缀的导入语句，例如```require("test")```，会依次测试它的后缀名

	},
	// cache: {
	//   type: 'filesystem',
	//   buildDependencies: {
	//     config: [__filename]
	//   },
	//   // cacheDirectory: path.resolve(__dirname, '.webpack_cache'),
	// },
	optimization: {
		splitChunks: {  //* 默认配置
			chunks: "all",
			maxSize: 60000,
			automaticNameDelimiter: ".",
			minChunks: 1,
			minSize: 3000,
			maxAsyncRequests: 30,
			maxInitialRequests: 30,
			enforceSizeThreshold: 20000,
			cacheGroups: {
				defaultVendors: {
					test: /[\\/]node_modules[\\/]/,
					priority: -10,
					reuseExistingChunk: true,
				},
				default: {
					minChunks: 2,
					priority: -20,
					reuseExistingChunk: true,
				},
				styles: {
					minSize: 0,
					test: /\.css$/,
					minChunks: 1
				}
			},
		},
	},
	module:{
   
		rules:[
			// {
			//   test:/main\.js$/, //*匹配模块路径
			//   use:[
			//     {
			//       loader:"./loaders-demo/test-loaders", // ./loaders-demo/test-loaders? changeVal=未知数 query 格式
			//       options:{
			//         changeVal:'未知数'
			//       }
			//     }, // *加载器
          
			//   ], // *匹配到值后使用哪些加载器
			// }, // *规则一 每个规则都是一个对象
			{
				test:/\main.js$/, //*匹配模块路径
				use:["./loaders-demo/test-loaders1","./loaders-demo/test-loaders2"]
			},
			{ test: /\.js$/,
				// exclude: /lodash/, //*通过module.rule.exclude或module.rule.include，排除或仅包含需要应用loader的场景
				// exclude:/node_modules/,
				// include:/src/,
				use:["thread-loader","babel-loader"],
				// options: {
				//   // 配置线程数
				//   threads: 4
				// }
			},
        
			{
				test:/\.css$/i, //*匹配模块路径
				use:[
					MiniCssExtractPlugin.loader,
					// "style-loader",
					{
						loader:"css-loader",
						options:{
							modules:{
								localIdentName:"[name]-[hash:5]"
							}
						}
					}],  // css变成 导出字符串 代码
			},
			{
				test:/\.(scss)|(sass)$/i, //*匹配模块路径
				use:[
					MiniCssExtractPlugin.loader,
					// "style-loader",
					{
						loader:"css-loader",
						options:{
							modules:{
								localIdentName:"[name]-[hash:5]"
							}
						}
					},"sass-loader"]
			},
			{
				test:/\.(pcss)|(sss)|(postcss)$/i, //*匹配模块路径
				use:[
					MiniCssExtractPlugin.loader,
					// "style-loader",
					{
						loader:"css-loader",
						options:{
							modules:{
								localIdentName:"[name]-[hash:5]"
							}
						}
					},"postcss-loader"]
			},
			{
				test:/\.(png)|(jpg)|(jpeg)|(gif)$/, //*匹配模块路径
				use:[{
					loader: "./loaders-demo/img-loader",
					options: {
						limit: 3000, //*3000字节以上使用图片，3000字节以内使用base64
						filename: "img-[contenthash:5].[ext]"
					}
				}],
        
			},
			// {
			//   test:/\.js$/, //*匹配模块路径
			//   use:["./loaders-demo/test-loaders3","./loaders-demo/test-loaders4"]
			// }
		], //* 匹配的匹配规则
		// noParse: /jquery|lodash/, //*不要解析某个模块 不解析正则表达式匹配的模块，通常用它来忽略那些大型的单模块库，以提高**构建性能**
	},
	// externals: {
	//   jquery: "$",
	//   lodash: "_"
	// }, //* 从最终的bundle中排除掉配置的配置的源码，例如，入口模块是 这比较适用于一些第三方库来自于外部CDN的情况，这样一来，即可以在页面中使用CDN，又让bundle的体积变得更小，还不影响源码的编写
 
  
	plugins: [
		new HtmlWebpackPlugin(
			{
				inject:"body",  // 插入那个标签下
				filename: "index.html",  // 生成文件名
				scriptLoading:"blocking",  // 加载方式
				template:"../public/index.html",  // 模板
				chunks:["main"]  // 指定要包含在 HTML 文件中的代码块 (chunk)。如果设置为空数组，则不添加任何代码块。如果未指定，则默认情况下将包含所有代码块。
			}),
		// new HtmlWebpackPlugin( {
		//   inject:'body',  // 插入那个标签下
		//   filename: 'index.html',  // 生成文件名
		//   scriptLoading:'blocking',  // 加载方式
		//   template:'../public/index.html',  // 模板
		//   chunks:['index']  // 指定要包含在 HTML 文件中的代码块 (chunk)。如果设置为空数组，则不添加任何代码块。如果未指定，则默认情况下将包含所有代码块。
		// }),
		new HtmlWebpackPlugin(
			{
				inject:"body",  // 插入那个标签下
				filename: "about.html",  // 生成文件名
				scriptLoading:"blocking",  // 加载方式
				template:"../public/about.html",  // 模板
				chunks:["about"]  // 指定要包含在 HTML 文件中的代码块 (chunk)。如果设置为空数组，则不添加任何代码块。如果未指定，则默认情况下将包含所有代码块。

			}),
		new CleanWebpackPlugin(
			{
				cleanOnceBeforeBuildPatterns: ["**/*", "!**/*.html","!dll","!dll/"],
			}
		), //* 如果你的源代码比较大且构建时间比较长，为了优化开发体验，你可能希望在开始构建前手动清空输出目录。你可以通过在 package.json 中添加一个 npm 脚本来实现这一点，例如： rimraf dist && webpack --mode production
		new DeadCodePlugin({
			patterns: [
				"**/*", // 只扫描src路径下所有文件
			],
			// exclude: [
			//     './**/mapping.xml',
			//     './**/*.md',
			// ],
			log: "none", // 不输出log
			exportJSON: "./analysis" // 结果生成到analysis路径下
		}),

		new pluginDemo(),
		new webpack.DefinePlugin({
			PI: "Math.PI", // const PI = Math.PI
			VERSION: "\"1.0.0\"", // VERSION = "1.0.0"
			DOMAIN: JSON.stringify("wsy.com")  // DOMAIN = "duyi.com"
		}),

		new MiniCssExtractPlugin(
			{
				// 打包 css 代码 到文件中
				filename: "css/[name].css",
				chunkFilename: "css/common.[hash:5].css" // 针对公共样式的文件名
			}
		),
		new PurgeCSSPlugin({
			paths: glob.sync(path.join(__dirname, "src/**/*.{html,js}")),
		}),
		new CmpressionWebpackPlugin({
			test: /\.js/,
			minRatio: 0.5
		})
		// new DashboardPlugin(),
		// new WebpackBuildNotifierPlugin({
		//   title: 'wangshunyu webpack setting',
		//   suppressSuccess: false,
		// }),
		// new webpack.ProvidePlugin({
		//     $: 'jquery',
		//     _: 'lodash'
		// })

		// new BundleAnalyzerPlugin(),
      


	],
	stats: {
		// All:true
    
		builtAt: true, // 显示构建日期和时间
		// modules:false,
		// chunkModules:false,
		// entrypoints:false,
    
	},

}
